package net.shopxx.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import net.shopxx.constant.AccountsConstant;
import net.shopxx.dao.AccountsDao;
import net.shopxx.dto.TbOrderDTO;
import net.shopxx.entity.AccountsItem;
import net.shopxx.entity.ShuaItem;
import net.shopxx.excel.excel.ExcelFile;
import net.shopxx.pager.AccountsPageable;
import net.shopxx.pager.Page;
import net.shopxx.service.AccountsService;
import net.shopxx.service.AdminService;
import net.shopxx.service.ShuaService;

/**
 * Service - 账务处理服务
 * 
 * @author frankie
 * @version 3.0
 */
@Service("accountsServiceImpl")
public class AccountsServiceImpl extends BaseServiceImpl<AccountsItem, Long> implements AccountsService {

	private Log log = LogFactory.getLog(this.getClass());

	@Resource(name = "adminServiceImpl")
	private AdminService adminService;

	@Resource(name = "shuaServiceImpl")
	private ShuaService shuaService;

	@Resource(name = "accountsDaoImpl")
	private AccountsDao accountsDao;

	@Resource(name = "accountsDaoImpl")
	public void setBaseDao(AccountsDao accountsDao) {
		super.setBaseDao(accountsDao);
	}

	@Override
	@Transactional
	@CacheEvict(value = "accountsItem", allEntries = true)
	public void save(AccountsItem accountsItem) {
		super.save(accountsItem);
		accountsDao.flush();
	}

	@Override
	public void dealWithTbOrder(ExcelFile ef) {
		int rows = ef.getRows(AccountsConstant.FIRST_PAGE);
		// 将excel中数据放入List
		ArrayList<TbOrderDTO> orderList = new ArrayList<TbOrderDTO>();
		HashSet<String> orderSet = new HashSet<String>();
		for (int i = 1; i < rows; i++) {
			TbOrderDTO order = new TbOrderDTO();
			boolean success = ef.row2Bean(i, order);
			if (success && order.getOrderId() != null) {
				orderList.add(order);

				if (order.getStatus() == AccountsConstant.TB_ORDER_STATUS_NORMAL) {
					orderSet.add(order.getBuyerUserName());
				}
			}
		}

		// 翻转List，从最远日期开始操作
		Collections.reverse(orderList);
		for (TbOrderDTO order : orderList)
			try {
				inputTbOrder(order, orderSet);
			} catch (Exception e) {
				log.error(e);
			}
	}

	private void inputTbOrder(TbOrderDTO order, HashSet<String> orderSet) throws Exception {

		Integer status = order.getStatus();
		// 当该订单关闭或未付款时，
		if (status == AccountsConstant.TB_ORDER_STATUS_CLOSED || status == AccountsConstant.TB_ORDER_STATUS_UNPAID) {

			// 1.当前excel中是否有成功订单
			if (orderSet.contains(order.getBuyerUserName())) {
				return;
			}

			Calendar c = Calendar.getInstance();
			c.add(Calendar.DATE, -7);

			// 2.查询七天之内是否存在相同用户的订单
			Long exist = accountsDao.countByTbUserName(order.getBuyerUserName(), c.getTime(), null);

			if (exist > 0) {
				return;
			}
		}

		// 查询该订单是否已被录入
		Long exist = accountsDao.countByOrderTbId(order.getOrderId());
		if (exist > 0) {
			return;
		}

		// 订单不关闭 && 不是未付款 则进行刷单信息处理
		if (status != AccountsConstant.TB_ORDER_STATUS_CLOSED && status != AccountsConstant.TB_ORDER_STATUS_UNPAID) {
			// 处理刷单数据
			dealwithShuaOrder(order);
		}

		String operator = adminService.getCurrentUsername();
		AccountsItem ai = new AccountsItem();

		ai.setOrderId(order.getOrderId());
		ai.setUserName(order.getBuyerUserName());
		ai.setAlipay(order.getBuyerAlipay());
		ai.setStoreId(order.getStoreIdByStoreName());
		ai.setPostage(order.getPostage());
		ai.setRealPaidFee(order.getRealPaidFee());
		ai.setBuyerServiceCharge(order.getFloatBuyerServiceCharge());
		ai.setSellerServiceCharge(order.getSellerServiceCharge());
		ai.setStatus(status);
		ai.setName(order.getBuyersName());
		ai.setAddress(order.getBuyersAddr());
		ai.setNewAddress(order.getModifiedAddr());
		ai.setContactNumber(order.getContactNumber());
		ai.setMobileNumber(order.getMobileNumber());
		ai.setOrderTime(order.getOrderTime());
		ai.setPaidTime(order.getPaidTime());
		ai.setGoodsTitle(order.getGoodsTitle());
		ai.setTrackingNumber(order.getTrackingNumber());
		ai.setBuyersMessage(order.getBuyersMessage());
		ai.setGoodsTotal(order.getGoodsTotal());
		ai.setIsMobile(order.getIsMobileOrder());
		ai.setType(order.getOrderType());
		ai.setOperator(operator);
		save(ai);

	}

	private void dealwithShuaOrder(TbOrderDTO order) {

		Integer resolvedStatus;
		if (order.getOrderType() == AccountsConstant.ANALYZED_ORDER_TYPE_TB) {
			resolvedStatus = AccountsConstant.STATUS_SHUADAN_FAILED;
		} else if (order.getOrderType() == AccountsConstant.ANALYZED_ORDER_TYPE_SHUA) {
			resolvedStatus = AccountsConstant.STATUS_SHUADAN_RESOLVED;
		} else {
			resolvedStatus = AccountsConstant.STATUS_SHUADAN_FAILED;
		}

		List<ShuaItem> list = shuaService.getInitShuaOrder(order);
		// 只查询出一条，并且为init，则更新为(已处理<刷单订单且金额正确> | 已失败<非刷单订单 或者金额不正确>)
		if (list.size() == 1) {
			ShuaItem shua = list.get(0);

			if (shua.getStatus() == AccountsConstant.STATUS_SHUADAN_INIT) {
				if (Math.abs(shua.getSum() - order.getRealPaidFee()) < 0.01) {
					shua.setStatus(resolvedStatus);
					if (resolvedStatus == AccountsConstant.STATUS_SHUADAN_FAILED) {
						shua.setMemo("淘宝订单未打星标！淘宝星标状态：" + order.getOrderType());
					}
					shuaService.update(shua);
				} else {
					shua.setStatus(AccountsConstant.STATUS_SHUADAN_FAILED);
					shua.setMemo("刷单金额填写错误！刷单金额：" + shua.getSum());
					shuaService.update(shua);
				}
			}
			// (查出多条 或 未查出，且为刷单订单) 则新建一条状态为失败的刷单信息
		} else if ((list.size() == 0)) {
			if (order.getOrderType() == AccountsConstant.ANALYZED_ORDER_TYPE_SHUA) {
				ShuaItem shua = new ShuaItem();
				String operator = adminService.getCurrentUsername();
				shua.setName(order.getBuyerUserName());
				shua.setKeyword(order.getOrderId().toString());
				shua.setSum(order.getRealPaidFee());
				shua.setStoreId(order.getStoreIdByStoreName());
				shua.setPlatform(AccountsConstant.SHUADAN_DEFAULT_PLATFORM);
				shua.setQq(AccountsConstant.SHUADAN_DEFAULT_QQ);
				shua.setFromNick(AccountsConstant.SHUADAN_DEFAULT_FROM_NICK);
				shua.setOperator(operator);
				shua.setStatus(AccountsConstant.STATUS_SHUADAN_FAILED);
				shua.setMemo("未找到正确的刷单订单！");
				shuaService.save(shua);
			}else if(order.getOrderType() == AccountsConstant.ANALYZED_ORDER_TYPE_SHUA_XU){
				ShuaItem shua = new ShuaItem();
				shua.setName(order.getBuyerUserName());
				shua.setKeyword(order.getOrderId().toString());
				shua.setSum(order.getRealPaidFee());
				shua.setStoreId(order.getStoreIdByStoreName());
				shua.setPlatform(AccountsConstant.SHUADAN_XU_PLATFORM);
				shua.setQq(AccountsConstant.SHUADAN_XU_QQ);
				shua.setFromNick(AccountsConstant.SHUADAN_XU_FROM_NICK);
				shua.setOperator("XU");
				shua.setStatus(AccountsConstant.STATUS_SHUADAN_RESOLVED);
				shua.setMemo("长兴水木花都刷单！");
				shuaService.save(shua);
			}else if(order.getOrderType() == AccountsConstant.ANALYZED_ORDER_TYPE_SHUA_QT1366){
				ShuaItem shua = new ShuaItem();
				shua.setName(order.getBuyerUserName());
				shua.setKeyword(order.getOrderId().toString());
				shua.setSum(order.getRealPaidFee());
				shua.setStoreId(order.getStoreIdByStoreName());
				shua.setPlatform(AccountsConstant.SHUADAN_QT1366_PLATFORM);
				shua.setQq(AccountsConstant.SHUADAN_QT1366_QQ);
				shua.setFromNick(AccountsConstant.SHUADAN_QT1366_FROM_NICK);
				shua.setOperator("QT1366");
				shua.setStatus(AccountsConstant.STATUS_SHUADAN_RESOLVED);
				shua.setMemo("QT1366刷单！");
				shuaService.save(shua);
			}
		}
	}

	@Override
	public Page<AccountsItem> findStatsPage(AccountsPageable pageable) {
		return accountsDao.findStatsPage(pageable);
	}

	@Override
	public Float findStatsSum(AccountsPageable pageable) {
		return accountsDao.findStatsSum(pageable);
	}

	@Override
	public Long findStatsCount(AccountsPageable pageable) {
		return accountsDao.findStatsCount(pageable);
	}

}
